package java_thinking.unit_21.concurrentutil;

/**
 * @Desc:   原子类型
 * @author: cww
 * @DateTime: 2019/7/26 8:37
 */

/**
 * 1.所有原子类型类中的一个获取内存空间相对位置的方法：
 *      1.long valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
 *      2.int base = unsafe.arrayBaseOffset(int[].class);
 *      3.见VISIO java对象内存占位示意图；
 *      一个java对象占用的内存空间包括：对象头+实例数据+对齐填充，而数组对象和普通对象头占用空间不同，见：
 *      https://blog.csdn.net/qlmmys/article/details/53213857
 * 2.AtomicInteger：见xmind
 * 4.AtomicIntegerArray:见xmind
 * 5.AtomicIntegerFieldUpdater:见xmind
 * 6.LongAdder:LongAdder可以代替AtomicLong吗？ 见xmind，Striped64.longAccumulate注释.txt ,visio LongAdder的优化思想，
 * 7.由 Striped64 的 Contended 注解引申的伪共享问题 见xmind Striped64，见visio 缓存伪共享示意
 *      参考：https://www.cnblogs.com/Binhua-Liu/p/5620339.html
 *            https://www.cnblogs.com/niutao/p/10567822.html
 * 8.AtomicReference:见xind
 *  AtomicReference的一般使用模式如下：
 *      AtomicReference<Object> ref = new AtomicReference<>(new Object());
 *      Object oldCache = ref.get();
 *
 *      // 对缓存oldCache做一些操作
 *      Object newCache  =  someFunctionOfOld(oldCache);
 *
 *      // 如果期间没有其它线程改变了缓存值，则更新
 *      boolean success = ref.compareAndSet(oldCache , newCache);
 *
 */

public class AtomicTheory {
}

/**
 * JDK1.8之前伪共享解决方式-padding方式
 */
class DataPadding{
    //防止与前一个对象产生伪共享
    long a1,a2,a3,a4,a5,a6,a7,a8;
    int value;
    long modifyTime;
    /**
     * 防止不相关变量伪共享;
     */
    long b1,b2,b3,b4,b5,b6,b7,b8;
    boolean flag;
    long c1,c2,c3,c4,c5,c6,c7,c8;
    long createTime;
    char key;
    //防止与下一个对象产生伪共享
    long d1,d2,d3,d4,d5,d6,d7,d8;
}

/**
 * JDK1.8之后解决方式- Contended注解方式
 * 类前加上代表整个类的每个变量都会在单独的cache line中
 */
@sun.misc.Contended
@SuppressWarnings("restriction")
class ContendedData {
    int value;
    long modifyTime;
    boolean flag;
    long createTime;
    char key;
}

/**
 * 属性前加上时需要加上组标签
 */
@SuppressWarnings("restriction")
class ContendedGroupData {
    @sun.misc.Contended("group1")
    int value;
    @sun.misc.Contended("group1")
    long modifyTime;
    @sun.misc.Contended("group2")
    boolean flag;
    @sun.misc.Contended("group3")
    long createTime;
    @sun.misc.Contended("group3")
    char key;
}